<?php
declare(strict_types=1);

namespace App\User\Controller;

use App\Common\Constants\ErrorCode;
use App\Common\Controller\AbstractController;
use App\Third\Service\Sms\SmsService;
use App\User\Service\MemberService;
use App\User\Service\UserService;
use App\Resource\Service\ShopService;
use EasyWeChat\Kernel\Exceptions\DecryptException;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\Middlewares;
use App\Common\Middleware\JwtAuthMiddleware;
use App\Common\Middleware\PermissionMiddleware;
use Hyperf\HttpServer\Contract\RequestInterface;
use Psr\SimpleCache\CacheInterface;

/**
 * @Controller()
 */
class LoginController extends AbstractController
{

    /**
     * @Inject()
     * @var UserService
     */
    private $userService;

    /**
     * @Inject()
     * @var MemberService
     */
    private $memberService;

    /**
     * @Inject()
     * @var ShopService
     */
    private $shopService;

    /**
     * @Inject()
     * @var CacheInterface
     */
    protected $cache;
    /**
     * @Inject()
     * @var SmsService
     */
    private $smsService;
    /**
     * 后台管理员登录.
     * @RequestMapping(path="/v1/user/login", methods="post")
     * @return array
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function login()
    {
        $username = $this->request->input('username');
        $password = $this->request->input('password');
        if(!$username || !$password){
            return $this->failed(ErrorCode::SYSTEM_INVALID);
        }
        $res = $this->userService->login($username, $password);
        if (!$res['code']) {
            return $this->success($res['data'], '登录成功');
        } else {
            return $this->failed($res['code']);
        }
    }

    /**
     * 获取当前用户信息
     * @RequestMapping(path="/v1/user/current", methods="get")
     * @Middlewares({
     *     @Middleware(JwtAuthMiddleware::class),
     *     @Middleware(PermissionMiddleware::class)
     * })
     *
     * @return array
     */
    public function currentInfo()
    {
        $result = $this->userService->getCurrentInfo();
        return $this->success($result, '获取成功');
    }


    /**
     * 商家端用户登录.
     * @RequestMapping(path="/v1/app/user/login", methods="post")
     * @return array
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function appLogin()
    {
        $phone = $this->request->input('phone');
        $password = $this->request->input('password');
        // 参数验证 手机号登录验证
        if (!$phone || !$password) {
            return $this->failed(ErrorCode::MISSING_PARAMETER);
        }
        // 手机号格式错误
        if (!preg_match("/^1[345789]\d{9}$/", $phone)) {
            return $this->failed(ErrorCode::PHONE_ERROR);
        }
        $result = $this->userService->getAppLogin($phone,$password);
        if (!$result['code']){
            $result = $result['data'];
            //用户信息验证
            $field = [
                'admin_users.id as user_id',
                'admin_users.username',
                'admin_users.password',
                'admin_users.phone',
                'us.shop_id',
            ];
            $user = $this->userService->getUserManul(['admin_users.phone' => $phone],$field);
            if (empty($user)){
                return $this->failed(ErrorCode::ERROR_BY_USER_BY_SHOP);
            }
            $res = $this->shopService->getInfoById(intval($user->shop_id));
            $res = $res['data'];
            $resArr = [
                'token' => $result['token'],
                'exp' => $result['exp'],
                'user_id' => $user->user_id,
                'username' => $user->username,
                'phone' => $user->phone,
                'last_login_at' => $user->last_login_at,
                'shop_id' => $user->shop_id,
                'shop_name' => $res['shop_name'],
                'status' => $res['status'],
                'longitude' => $res['longitude'],
                'latitude' => $res['latitude'],
                'start_time' => $res['start_time'],
                'end_time' => $res['end_time'],
                'logo' => $res['logo'],
            ];
            return $this->success($resArr, '登录成功');
        }else{
            return $this->failed($result['code']);
        }

    }

    /**
     * 小程序微信授权登录
     * @RequestMapping(path="/v1/api/wechat/auth", methods="post")
     * @return array
     * @throws DecryptException
     * @throws InvalidConfigException
     * @author liule
     */
    public function miniAppLogin()
    {
        $code = $this->request->input('code');
        $encryptedData = $this->request->input('encryptedData');
        $iv = $this->request->input('iv');
        $bdUid = $this->request->input('ground_promotion_user_id',0);
        $uinfo = $this->request->input('userInfo');
        if (!$code || !$encryptedData || !$iv) {
            return $this->failed(ErrorCode::SYSTEM_INVALID);
        }
        $result = $this->memberService->getWechatUserInfoByAuth($code, $iv, $encryptedData, (int)$bdUid, $uinfo);
        if (!$result['code']) {
            return $this->failed($result['errorCode']);
        }
        return $this->success($result['data'], $result['msg']);
    }

    /**
     * 商家APP修改密码
     * @RequestMapping(path="/v1/app/login/forgetPassword", methods="post")
     * @param RequestInterface $request
     * @return array
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function forgetPassword(RequestInterface $request)
    {
        $params = $request->all();
        //参数验证
        if(empty($params['phone']) || empty($params['auth_code']) || empty($params['new_password'])){
            return $this->failed(ErrorCode::MISSING_PARAMETER);
        }
        //用户是否存在
        $isUser = $this->userService->getUserInfo($params['phone']);
        if (is_null($isUser)){
            return $this->failed(ErrorCode::ERROR_USERNAME);
        }
        //验证码验证
        $cacheCode = $this->cache->get($params['phone']);
        if((int)$params['auth_code'] !== $cacheCode){
            return $this->failed(ErrorCode::PHONE_CODE_ERROR);
        }
        $this->cache->delete($params['phone']);
        $updateData = ['password' => password_hash($params['new_password'],PASSWORD_DEFAULT)];
        $result = $this->userService->updatePassword($params['phone'],$updateData);
        if($result){
            return $this->success('', '修改成功');
        }
        return $this->failed(ErrorCode::ERROR_BY_PASSWORD);
    }

    /**
     * 获取验证码
     * @RequestMapping(path="/v1/app/login/sendAuthCode", methods="post")
     * @param RequestInterface $request
     * @return array
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function sendAuthCode(RequestInterface $request)
    {
        $phone = $this->request->input('phone');
        if(!$phone){
            return $this->failed(ErrorCode::PHONE_ERROR);
        }
        // 手机号是否存在
        $user = $this->userService->getUserInfo($phone);
        if (!$user){
            return $this->failed(ErrorCode::ERROR_USERNAME);
        }
        $code = mt_rand(1000, 9999);
        $this->smsService->send($phone, $code);
        $this->cache->set($phone, $code, 300);
        return $this->success('', '操作成功');
    }
}
